var playerStateService = require('../../../services/playerStateService');
var killerRoomDao = require('../../../dao/killer/killerRoomDao');
var userTempInfoDao = require('../../../dao/hideAndSeek/userTempInfoDao');
var KillerRoom = require('../../../domain/killer/killerRoom');
module.exports = function (app) {
    return new Handler(app);
};

var Handler = function (app) {
    this.app = app;
};

var handler = Handler.prototype;

/**
 * New client entry chat server.
 *
 * @param  {Object}   msg     request message
 * @param  {Object}   session current session object
 * @param  {Function} next    next stemp callback
 * @return {Void}
 */
handler.enter = function (msg, session, next) {
    var self = this;
    var rid = msg.rid;
    var uid = msg.username + '*' + rid;
    var game = msg.game || '';
    var sessionService = self.app.get('sessionService');

    if (msg.username == null || msg.rid == null) {
        next(null, {
            code:400,
            error: 'param error'
        });
        return;
    }

    //duplicate log in
    if (!!sessionService.getByUid(uid)) {
        next(null, {
            code: 500,
            error: true
        });
        return;
    }

    session.bind(uid);
    session.set('rid', rid);
    session.push('rid', function (err) {
        if (err) {
            console.error('set rid for session service failed! error is : %j', err.stack);
        }
    });

    session.on('closed', onUserLeave.bind(null, self.app, game));

    // put user into channel
    if (game === 'hideAndSeek') {

        console.log("enter hideAndSeek game");
        self.app.rpc.hideAndSeek.chatRemote.add(session, uid, self.app.get('serverId'), rid, true, function (users) {
            next(null, {
                code: 200,
                users: users
            });
        });

    } else if (game === 'killer') {
        console.log("enter killer game");
        killerRoomDao.getRoom(rid, function (err, room) {
            console.log('room: ' + room);
            if (room == null || room.id == null) {
                next(null, {
                    code: 500,
                    reason: 'room does not exist'
                });
            } else if (room.state === KillerRoom.STATE.CLOSED) {
                next(null, {
                    code: 500,
                    reason: 'room was dismissed'
                });
            } else {
                playerStateService.inKillerGame(msg.username, JSON.stringify(msg), function (notUsed) {
                    self.app.rpc.killer.chatRemote.add(session, uid, self.app.get('serverId'), rid, true, function (users) {
                        next(null, {
                            code: 200,
                            users: users
                        });
                    });
                });
            }

        });

    } else {
        self.app.rpc.chat.chatRemote.add(session, uid, self.app.get('serverId'), rid, true, function (users) {
            next(null, {
                code: 200,
                users: users
            });
        });
    }
};

/**
 * support killer only
 * @param msg
 * @param session
 * @param next
 */
handler.reenter = function (msg, session, next) {
    var self = this;
    var rid = msg.rid;
    var uid = msg.username + '*' + rid;
    var game = msg.game || '';
    var sessionService = self.app.get('sessionService');

    killerRoomDao.getRoom(rid, function (err, room) {
        if (room == null || room.id == null) {
            next(null, {
                code: 500,
                reason: 'room does not exist'
            });
        } else if (room.state === KillerRoom.STATE.CLOSED) {
            next(null, {
                code: 500,
                reason: 'room was dismissed'
            });
        } else {
            // duplicate log in
            if (!!sessionService.getByUid(uid)) {
                // old session
                console.log('old session');
                console.log(uid);
                console.log(session.get('rid'));
                console.log(sessionService.getByUid(uid).toString());
                if (!session.get('rid')) {
                    session.set('rid', rid);
                    session.push('rid', function (err) {
                        if (err) {
                            console.error('set rid for session service failed! error is : %j', err.stack);
                        }
                    });
                }
            } else {
                // new session
                session.bind(uid);
                session.set('rid', rid);
                session.push('rid', function (err) {
                    if (err) {
                        console.error('set rid for session service failed! error is : %j', err.stack);
                    }
                });
                session.on('closed', onUserLeave.bind(null, self.app, game));
            }

            self.app.rpc.killer.chatRemote.getAllUsers(session, rid, false, function (users) {
                if (users && users.indexOf(msg.username) > -1) {
                    next(null, {
                        code: 200,
                        users: users
                    });
                } else {
                    self.app.rpc.chat.chatRemote.add(session, uid, self.app.get('serverId'), rid, true, function (users) {
                        next(null, {
                            code: 200,
                            users: users
                        });
                    });
                }
            });
        }
    });

};

/**
 * User log out handler
 *
 * @param {Object} app current application
 * @param {Object} session current session object
 *
 */
var onUserLeave = function (app, game, session) {
    if (!session || !session.uid) {
        return;
    }
    if (game === 'hideAndSeek') {
        app.rpc.hideAndSeek.chatRemote.kick(session, session.uid, app.get('serverId'), session.get('rid'), null);
    } else if (game === 'killer') {
        app.rpc.killer.chatRemote.kick(session, session.uid, app.get('serverId'), session.get('rid'), null);
    } else {
        app.rpc.chat.chatRemote.kick(session, session.uid, app.get('serverId'), session.get('rid'), null);
    }
};